package tcpClient

import (
	wait "CSCredis/util/sync"
	"net"
	"sync"
	"time"
)

/**
 * @Author: hejing@szlabsun.com
 * @Description: 封装扩展客户端对象 包括conn连接 扩展密码等第一次连接会写入的数据
 * @File:  client
 * @Version: 1.0.0
 * @Date: 2021/6/24 16:16
 */
// public class ClientImpl implements interface/server/connection
type ClientImpl struct { // 此结构体实现了 interface/server/connection接口
	conn     net.Conn
	password string
	// 这里封装了一个计数器 此客户端每次做一次任务时调用一次wait.add 完成时调用wait.done
	waitingReply wait.Wait
	// 整一个锁，
	mu sync.Mutex
}

func NewClient(conn net.Conn) *ClientImpl {
	return &ClientImpl{
		conn: conn,
	}
}
func (c *ClientImpl) GetConn() net.Conn {
	return c.conn
}

// Close disconnect with the client
// 关闭之前先等待client将剩余任务完成，但最多等待timeout的时间
func (c *ClientImpl) Close() error {
	c.waitingReply.WaitWithTimeout(10 * time.Second)
	_ = c.conn.Close()
	return nil
}

// Write sends response to client over tcp connection
// 往tcp客户端写入response
func (c *ClientImpl) Write(b []byte) error {
	if len(b) == 0 {
		return nil
	}
	//c.mu.Lock()
	c.waitingReply.Add(1)
	defer func() {
		c.waitingReply.Done()
		//c.mu.Unlock()
	}()

	_, err := c.conn.Write(b)
	return err
}

// SetPassword stores password for authentication
func (c *ClientImpl) SetPassword(password string) {
	c.password = password
}

// GetPassword get password for authentication
func (c *ClientImpl) GetPassword() string {
	return c.password
}
